/*
 * Remoteproc Virtio Framework
 *
 * Copyright(c) 2018 Xilinx Ltd.
 * Copyright(c) 2011 Texas Instruments, Inc.
 * Copyright(c) 2011 Google, Inc.
 * All rights reserved.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

#ifndef REMOTEPROC_VIRTIO_H
#define REMOTEPROC_VIRTIO_H

#include <metal/io.h>
#include <metal/list.h>
#include <openamp/virtio.h>

#if defined __cplusplus
extern "C" {
#endif

/* 受16位数据类型限制的vdev的最大vring描述符个数 */
#define RPROC_MAX_VRING_DESC USHRT_MAX

/* 定义用户应该实现的vdev通知功能 */
typedef int (*rpvdev_notify_func)(void *priv, uint32_t id);

/**
 * struct remoteproc_virtio
 * @priv pointer to private data
 * @vdev_rsc address of vdev resource
 * @vdev_rsc_io metal I/O region of vdev_info, can be NULL
 * @notify notification function
 * @vdev virtio device
 * @node list node
 */
struct remoteproc_virtio {
    void *priv;
    void *vdev_rsc;
    struct metal_io_region *vdev_rsc_io;
    rpvdev_notify_func notify;
    struct virtio_device vdev;
    struct metal_list node;
};

/**
 * @brief      创建Rproc Virtio虚拟设备.
 * @param[in]  role      虚拟设备角色, 取值VIRTIO_DEV_DRIVER或VIRTIO_DEV_DEVICE.
 * @param[in]  notifyid  Virtio设备通知ID.
 * @param[in]  rsc       指向Virtio设备资源的指针.
 * @param[in]  rsc_io    指向Virtio设备资源I/O区域的指针.
 * @param[in]  priv      指向Virtio设备私有数据的指针.
 * @param[in]  notify    虚拟设备或虚拟队列通知回调函数.
 * @param[in]  rst_cb    Virtio设备复位回调函数.
 * @return     成功返回指向创建的虚拟设备的指针, 设备返回NULL.
 */
struct virtio_device * rproc_virtio_create_vdev(unsigned int role,
    unsigned int notifyid, void *rsc, struct metal_io_region *rsc_io,
    void *priv, rpvdev_notify_func notify, virtio_dev_reset_cb rst_cb);

/**
 * @brief      移除Rproc Virtio虚拟设备.
 * @param[in]  vdev 指向Virtio设备的指针.
 */
void rproc_virtio_remove_vdev(struct virtio_device *vdev);

/**
 * @brief Initialize rproc virtio vring
 *
 * @param vdev		Pointer to the virtio device
 * @param index		vring index in the virtio device
 * @param notifyid	remoteproc vring notification id
 * @param va		vring virtual address
 * @param io		Pointer to vring I/O region
 * @param num_descs	Number of descriptors
 * @param align		vring alignment
 *
 * @return 0 for success, negative value for failure.
 */
int rproc_virtio_init_vring(struct virtio_device *vdev, unsigned int index,
    unsigned int notifyid, void *va, struct metal_io_region *io,
    unsigned int num_descs, unsigned int align);

/**
 * @brief      Remoteproc得到通知.
 * @param[in]  vdev     指向virtio设备的指针.
 * @param[in]  notifyid 通知ID.
 * @return     成功返回0, 失败返回错误码(负数).
 */
int rproc_virtio_notified(struct virtio_device *vdev, uint32_t notifyid);

/**
 * @brief Blocking function, waiting for the remote core is ready to start
 * communications.
 *
 * @param vdev	Pointer to the virtio device
 *
 * @return true when remote processor is ready.
 */
void rproc_virtio_wait_remote_ready(struct virtio_device *vdev);

#if defined __cplusplus
}
#endif

#endif /* REMOTEPROC_VIRTIO_H */
